from geocoder import ip
from geocoder.ipinfo import IpinfoQuery
from requests import get
from typing import Optional
from rich.table import Table
from rich.console import Console
from utils import (
    config,
    WeatherIndices,
    Unit, Language,
    Indices, IndicesType,
    get_location,
    format_time
)
from utils.type import _WeatherIndices

def weather_indices(
        location: Optional[str]=None,
        type: IndicesType=0,
        days: Indices=1,
        language: Language=None,
        unit: Unit=None
    ) -> _WeatherIndices:
    """
    Get weather indices

    Args:
        location: Location to get weather indices. Default: `None`
        type: Type of indices to get weather indices. Default: `0`
        days: Number of days to get weather indices. Default: `1`
        language: Language to get weather indices. Default: `None`
        unit: Unit to get weather indices. Default: `None`

    Raises:
        ValueError: Days must be in 1 or 3

    Returns:
        Weather indices
    """
    # Check days
    if days not in [1, 3]:
        raise ValueError('Days must be in 1 or 3')
    # Get location
    if location is None:
        location = 'me'
        g: IpinfoQuery = ip(location, timeout=1)
        loc = ','.join([str(g.latlng[1]), str(g.latlng[0])])
    else:
        loc = get_location(location)
    # Get language and unit
    if language is None:
        language = config.language
    if unit is None:
        unit = config.unit
    if isinstance(type, list):
        type = ','.join(map(str, type))
    # Get qweather api
    base_url = f'{config.base_url}/v7/indices/{days}d?type={type}&location={loc}&lang={language}&unit={unit}'
    headers = {'Authorization': f'Bearer {config.token}'}
    # Send request and get response in json format
    resp = get(url=base_url, headers=headers)
    result: WeatherIndices = resp.json()
    if 'daily' in result:
        return result['daily']

def print_indices(
        table: _WeatherIndices,
        days: Indices=1,
        unit: Unit=None
    ) -> None:
    """
    Print weather indices

    Args:
        table: Weather indices
        days: Number of days to get weather indices. Default: `1`
        unit: Unit to get weather indices. Default: `None`
    """
    # Check days
    if days not in [1, 2, 3]:
        raise ValueError('Days must be in 1, 2 or 3')
    # Get default unit
    if unit is None:
        unit = config.unit
    # Create Console
    console = Console()
    # Create Table
    t = Table(title=f'🌤️ Weather indices for {days} days', header_style='bold magenta')
    # Add columns
    t.add_column('日期', style='cyan', justify='center')
    t.add_column('指数名称', style='green', justify='left')
    t.add_column('等级', style='yellow', justify='center')
    t.add_column('分类', style='blue', justify='center')
    t.add_column('描述', style='white', justify='left')
    # Add rows
    for item in table:
        # Get level color based on level value
        level = item['level']
        if level in ['1', '2']:
            level_style = 'bold green'
        elif level in ['3', '4']:
            level_style = 'bold yellow'
        elif level in ['5', '6', '7']:
            level_style = 'bold red'
        # Get category color based on category text
        category = item['category']
        if category in ['良', '适宜', '良好', '不需要']:
            category_style = 'green'
        elif category in ['较好', '较适宜', '较舒适', '较少开启']:
            category_style = 'cyan'
        elif category in ['弱', '较弱', '较不宜', '较易发']:
            category_style = 'yellow'
        elif category in ['热', '不宜', '极易发', '不舒适']:
            category_style = 'red'
        else:
            category_style = 'white'
        # Add row
        t.add_row(
            format_time(item['date'], '%Y/%m/%d'),
            item['name'],
            f'[{level_style}]{level}[/]',
            f'[{category_style}]{category}[/]',
            item['text']
        )
    # Print table
    console.print(t)
